<?php

interface IForm {
    function __construct($data=null);
}


/**
 * Form
 * ..more describing facts are coming
 */
class Form {
    
    var $cleaned_data = array();
    var $data = array();
    var $form_fields = array();
    var $validation_error = false;
    
    function Form($data=null){
        $this->form_fields = $this->__get_defined_form_fields();
        #echo pr($this->form_fields);
        #exit;
        $this->data = $data;
        if($data != null && !empty($this->data)){
            $this->validate_fields();
        }
    }
    
    function is_valid(){
        if($this->data != null && !empty($this->data)){
            $clean_methods = $this->__get_clean_methods();
            foreach($clean_methods as $method){
                $this->{$method}();
            }
            if($this->validation_error){
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    }
    
    /**
     * Go through loaded values, not true validation
     * TODO: rename method to more propriate name
     * Parse pre-loaded values
     */
    protected function validate_fields(){
        # Core validation for fields to start with
        # Also copy submited values to the fields
        foreach($this->form_fields as $field_name=>$field){
            if(isset($field['type']) && $field['type'] == 'file'){
                # ONLY FOR FILE UPLOADING
                if( $this->data[$field_name]['name'] == ''){
                    $this->validation_error = true;
                    $this->form_fields[$field_name]['error_message'] = 'Ange ett v&auml;rde!';
                }
            } else {
                # NORMAL FIELDS
                
                # All widgets must be defined with this statement
                if( isset($field['widget']) && $field['widget'] == 'date_select_month_year'){
                    #$this->data[$field_name] = $this->data[$field_name.'_year'].'-'.$this->data[$field_name.'_month'].'-01';
                    if( isset($this->data[$field_name.'_month']) ){
                        # We now know the form has been sent POSTED
                        # Populate original field
                        $this->data[$field_name] = strtotime($this->data[$field_name.'_year'].'-'.$this->data[$field_name.'_month'].'-01');
                    } else {
                        # Populate generated fields, form being loaded for first time, NOT posted
                        if( isset($this->data[$field_name]) ){
                            $this->data[$field_name.'_month'] = date('n',$this->data[$field_name]);
                            $this->data[$field_name.'_year'] = date('Y',$this->data[$field_name]);
                        }
                    }
                    
                } else if( isset($this->data[$field_name]) && $this->data[$field_name] == ''){                    
                    if(isset($this->form_fields[$field_name]['blank']) && !$this->form_fields[$field_name]['blank']){
                        $this->validation_error = true;
                        $this->form_fields[$field_name]['error_message'] = 'Ange ett v&auml;rde!';
                    }
                }
                
                # Well, copy old values
                if( isset($this->data[$field_name]) ){
                    # Escape some bad stuff
                    $escaped = $this->data[$field_name];
                    $escaped = strip_tags($escaped);
                    $escaped = mysql_escape_string($escaped);
                    
                    $this->data[$field_name] = $escaped;
                    
                    $this->form_fields[$field_name]['value'] = $this->data[$field_name];
                }
                
            }
        }
        $this->cleaned_data = $this->data;
    }
    
    function raiseValidationError($msg){
        $this->validation_error = true;
        # Get the parent method call ->
        $called_from = debug_backtrace();
        $called_from = $called_from[1]['function'];
        $field_name = substr($called_from,strlen('clean_'));
        $this->form_fields[$field_name]['error_message'] = $msg;
    }
    
    /**
     * @Interface
     */
    function save(){
        
    }
    
    #function field($field_name, $label, $xtra='',$type='text'){
        #$my_field_name = array('label'=>$label,'blank'=>false,'type'=>$type, 'xtra'=>$xtra);
    #}
    function field($field_name){
        return $this->__field($field_name, $this->form_fields[$field_name] );
    }
    
    function __field($field_name, $field){
        $html = '';
        $xtra = ( isset($field['xtra'])) ? $field['xtra'] : '';
        $value = ( isset($field['value']) ) ? $field['value'] : '';
        $label_element = (isset($field['label'])) ? '<label for="id_'.$field_name.'">'.$field['label'].'</label>':'';
        $error_element = ($field['error_message'] != '') ? '<div class="error_container" id="">'.$field['error_message'].'</div>':'';
        
        if( isset($field['widget'])){
            $value = ( isset($field['value']) ) ? $field['value'] : '';
            $choices = ( isset($field['choices']) ) ? $field['choices'] : null;
            $input_element = $this->{'__'.$field['widget']}($field_name,$value,$choices);
        } else if( isset($field['type']) && ($field['type'] != 'text' && $field['type'] != 'file')){
            if($field['type'] == 'select'){
                # SELECT FIELD
                $input_element  = '<select name="'.$field_name.'" id="id_'.$field_name.'" '.$xtra.'>';
                foreach($field['choices'] as $key=>$choice){
                    if(isset($field['value']) && $field['value'] == $key){
                        $input_element .= '<option selected="selected" value="'.$key.'">';
                    } else {
                        $input_element .= '<option value="'.$key.'">';
                    }
                    $input_element .= $choice.'</option>';
                }
                $input_element .= '</select>';
            } else if($field['type'] == 'file'){
                #$input_element .= '<input type="button" value="not impl"/>';
            } else if($field['type'] == 'checkbox'){
                # CHECK-BOX
                $is_checked = ( isset($field['value']) && $field['value'] == '1' ) ? 'checked="checked"': '';
                $input_element = '<input type="hidden" name="'.$field_name.'" />';
                $input_element .= '<input type="checkbox" '.$is_checked.' value="1" name="'.$field_name.'" id="id_'.$field_name.'" '.$xtra.' />';
            } else if($field['type'] == 'radio'){
                # RADIO
                $input_element = '';
                foreach($field['choices'] as $key=>$choice){
                    if(isset($field['value']) && $field['value'] == $key){
                        $checked = 'checked="checked"';
                    } else {
                        $checked = '';
                    }
                    $input_element .= '<input '.$checked.' value="'.$key.'" type="radio" name="'.$field_name.'" id="id_'.$field_name.'_'.$key.'" '.$field['xtra'].'>';
                    $input_element .= '&nbsp;'.$choice.'&nbsp; ';
                }
            } else if($field['type'] == 'textarea' || $field['type'] == 'area'){
                # TEXT AREA
                $value = ( isset($field['value']) ) ? $field['value'] : '';
                $xtra = ( isset($field['xtra'])) ? $field['xtra'] : '';
                $input_element = '<textarea name="'.$field_name.'" id="id_'.$field_name.'" '.$xtra.'>'.$value.'</textarea>';
            } else if($field['type'] == 'hidden'){
                # HIDDEN FIELD
                $input_element = '<input name="'.$field_name.'" value="'.$value.'" id="id_'.$field_name.'" type="hidden" />';
                return $input_element;
            } else {
                # BUTTON
                $input_element = '<input type="button" value="not impl"/>';
            }
        } else if( isset($field['primary_key']) && $field['primary_key'] == true ) {
            $value = ( isset($field['value']) ) ? $field['value'] : '';
            $input_element = '<input name="'.$field_name.'" value="'.$value.'" id="id_'.$field_name.'" type="hidden" />';
        } else if( isset($field['foreign_key']) && $field['foreign_key'] == true ) {
            $value = ( isset($field['value']) ) ? $field['value'] : '';
            $input_element = '<input name="'.$field_name.'" value="'.$value.'" id="id_'.$field_name.'" type="hidden" />';
        } else {
            # Normal TEXTFIELD
            $type = ( isset($field['type'])) ? $field['type']:'text';
            $value = ( isset($field['value']) ) ? $field['value'] : '';
            $xtra = ( isset($field['xtra'])) ? $field['xtra'] : '';
            $input_element = '<input name="'.$field_name.'" value="'.$value.'" id="id_'.$field_name.'" type="'.$type.'" '.$xtra.'/>';
        }
        return $input_element;
    }
    
    function as_p(){
        $javascript = "
            <script>
            $(document).ready(function(){
                var is_focused = false;
                $('.regular-form').children().find('input').each(function(i){
                    if( $(this).attr('type') != 'hidden' && !is_focused){
                        $(this).focus();
                        is_focused = true;
                    } 
                });
                //$('.regular-form').children().find('input').eq(0).focus();
                $('.error_container').prev().find('select').eq(0).focus();
                $('.error_container').prev().find('input').eq(0).focus();
            });
            </script>
        ";
        $html = ''.$javascript;
        foreach($this->form_fields as $field_name=>$field){
            $input_element = $this->__field($field_name, $field);
            $label_element = (isset($field['label']) ) ? '<label for="id_'.$field_name.'">'.$field['label'].'</label>':'';
            $error_element = ($field['error_message'] != '') ? '<div class="error_container" id="">'.$field['error_message'].'</div>':'';
            
            if($field['type'] == 'hidden'){
                $html .= $input_element;
                $html .= $error_element;
            } else {
                $html .= "\n<p>\n";
                $html .= $label_element."\n";
                $html .= $input_element."\n";
                $html .= '</p>'."\n";
                $html .= $error_element;
            }
        }
        return $html;
    }
    
    private function __get_defined_form_fields(){
        $all_vars = get_class_vars( get_class($this));
        
        unset( $all_vars['data'] );
        unset( $all_vars['cleaned_data'] );
        unset( $all_vars['form_fields'] );
        unset( $all_vars['validation_error'] );
        
        foreach($all_vars as $key=>$field){
            $all_vars[$key] = $this->{$key};
            $all_vars[$key]['error_message'] = '';
        }
        
        return $all_vars;
    }
    
    private function __get_clean_methods(){
        $all_methos = get_class_methods( get_class($this) );
        
        $clean_methods = array();
        foreach($all_methos as $method){
            if( strpos($method,'clean_') !== false && strpos($method,'clean_') < 1){
                $clean_methods[] = $method;
            }
        }
        return $clean_methods;
    }
    
    /**
     * Widgets - hard coded 
     */
    private function __date_select_month_year($field_name, $value, $choices=null){
        $html = '<input type="hidden" value="'.$value.'" id="id_'.$field_name.'" name="'.$field_name.'" />';
        #$html = '';
        if($value == null || $value == ''){
            $value = time();
        }
        $cleaned_date = clean_date($value);
        # MONTHS
        $html .= '<select name="'.$field_name.'_month" id="id_'.$field_name.'_month">';
        $html .= '<option value="">V&auml;lj m&aring;nad...</option>'."\n";
        foreach(get_months() as $i => $month){
            $selected = ($i == (date('n',$cleaned_date)-1))?'selected="selected" ':'';
            $html .= '<option '.$selected.' value="'.($i+1).'">'.$month.'</option>'."\n";
        }
        $html .= '</select>&nbsp;'."\n\n";
        
        # YEARS
        $html .= '<select name="'.$field_name.'_year" id="id_'.$field_name.'_year">';
        $html .= '<option value="">V&auml;lj &aring;r...</option>'."\n";
        for($y=0; $y < 18; $y++){
            $y_out = ($y < 10)?"0$y":$y;
            $selected = ('20'.$y_out == date('Y',$cleaned_date) )?'selected="selected" ':'';
            $html .= '<option '.$selected.' value="20'.$y_out.'">20'.$y_out.'</option>'."\n";
        }
        $html .= '</select>'."\n\n";
        
        return $html;
    }
    
    /**
     * Widgets - hard coded 
     */
    function __select_multiple($field_name, $value, $choices){
        $html  = '<input type="hidden" value="'.$value.'" size="100" id="id_'.$field_name.'" name="'.$field_name.'" />';
        $html .= '<select multiple="multiple" size="7" name="_'.$field_name.'" id="_id_'.$field_name.'">';
        $html .= '<option value="">V&auml;lj projektmedlemmar...</option>'."\n";
        foreach($choices as $key=>$value){
            #$y_out = ($y < 10)?"0$y":$y;
            #$selected = ('20'.$y_out == date('Y',$cleaned_date) )?'selected="selected" ':'';
            $html .= '<option value="'.$key.'">'.$value.'</option>'."\n";
        }
        $html .= '</select>'."\n\n";
        #echo pr($choices);
        return $html;
    }
    
}

?>